package cn.ad.server.web.service;

import cn.ad.server.common.utils.BeanUtils;
import cn.ad.server.common.utils.monitor.MonitorHandler;
import cn.ad.server.domain.ad.*;
import cn.ad.server.domain.ad.vo.AdSpaceVO;
import cn.ad.server.domain.ad.vo.CampaignVO;
import cn.ad.server.domain.ad.vo.StrategyGroupVO;
import cn.ad.server.domain.ad.vo.StrategyVO;
import cn.ad.server.persistence.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Random;

@Service
public class AdService {

	static Logger logger = LoggerFactory.getLogger(AdService.class);

	@Autowired
	private AdSpaceRepository adSpaceRepository;

	@Autowired
	private CreativeRepository creativeRepository;

	@Autowired
	private StrategyRepository strategyRepository;

	@Autowired
	private ConfigRepository configRepository;

	@Autowired
	private AdTemplateRepository adTemplateRepository;

	@Autowired
	private PlatformRepository platformRepository;

	@Autowired
	private CampaignRepository campaignRepository;

	@Autowired
	private AreaPlatformMapRepository areaPlatformMapRepository;

	@Autowired
	private StrategyUserDmpMapRepository strategyUserDmpMapRepository;

	@Autowired
	private TagRepository tagRepository;
	
	@Autowired
	private GuidRepository guidRepository;
	
	private static final DecimalFormat df = new DecimalFormat("###0.00");

	@Value("${bid.adView.ratio}")
	private double configatio;

	static {
		df.setRoundingMode(RoundingMode.HALF_UP);
	}

	public void warmUpAdSpaces() {
		adSpaceRepository.warmUpAll();
	}

	public void warmUpCreative() {
		creativeRepository.warmUpCreative();
	}

	/**
	 * 判断是否选择第一次广告请求
	 * 
	 * @return
	 */
	public boolean isDeviceActivePolicySelectedFirst() {
		String deviceActivePolicy = configRepository.fetchDeviceActivePolicy();
		if ("first".equalsIgnoreCase(deviceActivePolicy)) {
			return true;
		} else if ("first".equalsIgnoreCase(deviceActivePolicy)) {
			return false;
		}
		return true;
	}

	/**
	 * 获取 AreaPlatformMap对象。
	 * 
	 * @param targetId
	 * @return
	 */
	public AreaPlatformMap fetchAreaPlatformMapByTargetId(int targetId) {
		return areaPlatformMapRepository.fetchAreaPlatformMapByTargetId(targetId);
	}

	/**
	 * 获取 userDmpId列表。
	 * 
	 * @param strategyId
	 * @param channelId
	 * @return
	 */
	public List<String> fetchUserDmpId(long strategyId, int channelId) {
		List<String> userDmpIds = strategyUserDmpMapRepository.fetchUserDmpId(strategyId, channelId);
		return userDmpIds;
	}

	/**
	 * 获取广告模板
	 * 
	 * @param tagId
	 * @return
	 */
	public AdTemplate fetchTemplateByTagId(String tagId) {
		try {
			return adTemplateRepository.fetchTemplateByTagId(tagId);
		} catch (Exception e) {
			logger.error("fetch AdTemplate error, tagId:{}", tagId, e);
		}
		return null;
	}

	/**
	 * 根据tagId 获取平台广告位匹配表PlatformAdspaceMap
	 * 
	 * @param tagId
	 * @return
	 */
	public PlatformAdspaceMap fetchAdspaceByTagId(String tagId, int channel) {
		try {
			return tagRepository.fetchAdspaceByTagId(tagId, channel);
		} catch (Exception e) {
			logger.error("fetch PlatformAdspaceMap error, tagId:{},channel:{}", tagId, channel, e);
		}
		return null;
	}

	/**
	 * 获取广告尺寸
	 * 
	 * @param tagId
	 * @return
	 */
	public PlatformTagSizeMap fetchSizeByTagId(String tagId) {
		PlatformTagSizeMap platformTagSizeMap = null;
		try {
			platformTagSizeMap = tagRepository.fetchSizeByTagId(tagId);
		} catch (Exception e) {
			logger.error("fetch PlatformTagSizeMap error, tagId:{}", tagId, e);
		}
		return platformTagSizeMap;
	}

	public Platform fetchPlatformById(Integer platformId) {
		try {
			return platformRepository.fetchPlatformById(platformId);
		} catch (Exception e) {
			logger.error("fetch Platform error, platformId:{}", platformId, e);
		}
		return null;
	}

	public Campaign fetchCampaignById(Integer campaignId) {
		try {
			return campaignRepository.fetchCampaignById(campaignId);
		} catch (Exception e) {
			logger.error("fetch Campaign error, platformId:{}", campaignId, e);
		}
		return null;
	}

	public List<Campaign> multiFetchCampaignByIds(Collection<Integer> campaignIds) {
		List<String> campaignKeys = new ArrayList<>();
		for (Integer integer : campaignIds) {
			campaignKeys.add(Campaign.cacheKey(integer));
		}
		return campaignRepository.multiFetchCampaignByIds(campaignKeys);
	}

	List<AdMaterial> calMaterialSize(List<AdMaterial> adMaterials, int thresholdWidth, double width, double height) {

		double min = 0.0d;
		boolean init = true;
		int minDivide = 0;
		List<AdMaterial> fitMaterials = new ArrayList<>();

		// 取宽度小于屏幕宽度的素材
		for (AdMaterial adMaterial : adMaterials) {
			if (adMaterial.getAdSize().getWidth() <= thresholdWidth) {
				double d = adMaterial.computeD(width, height);
				int divide = thresholdWidth - adMaterial.getAdSize().getWidth();
				d = Double.parseDouble(df.format(d));

				if (init) {
					fitMaterials.add(adMaterial);
					min = d;
					minDivide = divide;
					init = false;
				} else {
					if (d < min) {
						fitMaterials.clear();
						fitMaterials.add(adMaterial);
						min = d;
						minDivide = divide;
					} else if (d == min) {
						if (divide == minDivide) {
							fitMaterials.add(adMaterial);
						}

						if (divide < minDivide) {
							fitMaterials.clear();
							fitMaterials.add(adMaterial);
							minDivide = divide;
						}
					}
				}
			}
		}

		return fitMaterials;
	}

	/**
	 * to-do 筛选策略的逻辑
	 * 
	 * @param adSpace
	 * @return
	 */
	Strategy matchStrategy(AdSpace adSpace) {
		return null;
	}

	Creative matchCreative(AdSpace adSpace, Strategy strategy) {
		/**
		 * to-do 筛选创意的逻辑
		 */
		if (strategy != null) {
		}
		if (adSpace.getDefaultCreative() == null)
			return null;

		Creative c = creativeRepository.findById(adSpace.getDefaultCreative().getId());
		return c;
	}

	void matchNative(AdSpace adSpace) {
		if (adSpace.getDefaultCreative() == null)
			return;
		Creative c = creativeRepository.findById(adSpace.getDefaultCreative().getId());
		List<AdMaterialGroup> amgs = creativeRepository.findAdMaterialGroup(c);
		adSpace.setMatchAdMaterialGroups(amgs);
		adSpace.setMatchCreative(c);
		adSpace.setDefaultCreative(c);

	}

	/**
	 * @return
	 */
	// HIS 此方法没有被调用
	/*
	 * public AdSpace fetchAd(AdRequestCommand aCommand) { long s =
	 * System.currentTimeMillis(); AdSpace adSpace =
	 * adSpaceRepository.findAdSpaceById(aCommand.getAdSpaceId()); if (adSpace
	 * == null) throw new AdServerException("1", "No such AdSpace " +
	 * aCommand.getAdSpaceId()); logger.debug("adspace --------- {}",
	 * System.currentTimeMillis() - s);
	 * 
	 * // 匹配原生广告的逻辑 if (adSpace.getAdFormat() == AdFormat.AD_NATIVE) {
	 * matchNative(adSpace); logger.debug("native --------- {}",
	 * System.currentTimeMillis() - s); return adSpace; }
	 * 
	 * // 匹配策略 Strategy strategy = matchStrategy(adSpace);
	 * 
	 * // 匹配创意 Creative c = matchCreative(adSpace, strategy); if (c == null) {
	 * throw new AdServerException("2", "No creative matching"); }
	 * logger.debug("matchCreative --------- {}", System.currentTimeMillis() -
	 * s); if (CollectionUtils.isEmpty(c.getAdMaterials())) throw new
	 * AdServerException("4", "No AdMaterials");
	 * 
	 * // 筛选广告素材 AdMaterial adMaterial = this.chooseMaterial(c.getAdMaterials(),
	 * aCommand, adSpace); logger.debug("chooseMaterial --------- {}",
	 * System.currentTimeMillis() - s);
	 * adSpace.setMatchAdMaterials(c.getAdMaterials());
	 * adSpace.setMatchAdMaterial(adMaterial); adSpace.setMatchCreative(c);
	 * return adSpace; }
	 */

	public void warmUpAdMaterials() {
		this.creativeRepository.warmUpAdMaterials();
	}

	public void warmUpAdMaterialGroup() {
		this.creativeRepository.warmUpAdMaterialGroup();
	}

	public void warmUpAdTemplate() {
		creativeRepository.warmUpAdTemplate();
	}

	public void warmUpAdTemplateSpec() {
		creativeRepository.warmUpAdTemplateSpec();
	}

	public void warmUpRatio() {
		this.adSpaceRepository.warmRatio();
	}

	public String storeGuid(GuidValueObject guidVo, int channelId, AdSpace adSpace, Strategy s) {

		// guidVo.setAid(entry.getAdSpaceId());
		// guidVo.setSid(entry.strategyId);
		// guidVo.setCampaignId(entry.getCampaignId());
		
		if (s != null) {
			guidVo.setSid(s.getId());
			if (s.getCampaign() != null)
				guidVo.setCampaignId(s.getCampaign().getId());
		}

		if (adSpace != null) {
			guidVo.setAid(adSpace.getId());
			AdSpaceVO adSpaceVo = new AdSpaceVO();
			BeanUtils.copy(adSpace, adSpaceVo);
			guidVo.setAdSpaceVO(adSpaceVo);
		}
		if (s != null) {
			StrategyVO strategyVo = new StrategyVO();
			BeanUtils.copy(s, strategyVo);
			if (s.getStartTime() != null)
				strategyVo.setStartTimeSecond(s.getStartTime().getTime());
			if (s.getEndTime() != null)
				strategyVo.setEndTimeSecond(s.getEndTime().getTime());
			guidVo.setStrategyVO(strategyVo);
			if (s.getCampaign() != null) {
				CampaignVO campaignVo = new CampaignVO();
				BeanUtils.copy(s.getCampaign(), campaignVo);
				if (s.getCampaign().getEndTime() != null)
					campaignVo.setEndTimeSecond(s.getCampaign().getEndTime().getTime());
				guidVo.setCampaignVO(campaignVo);
			}
			if (s.getStrategyGroup() != null) {
				StrategyGroupVO strategyGroupVo = new StrategyGroupVO();
				BeanUtils.copy(s.getStrategyGroup(), strategyGroupVo);
				guidVo.setStrategyGroupVO(strategyGroupVo);
			}
		}
		guidVo.setSerializeVersion(GuidValueObject.CURRENT_VERSION);
		return this.guidRepository.storeGuid(guidVo, channelId);
	}

	/**
	 * 检查当前策略分组是否还有量
	 * 
	 * @return
	 */
	boolean haveStrategyGroupBalance(Strategy s, double singleBudget) {
		StrategyGroup sg = s.getStrategyGroup();
		double balance = strategyRepository.fetchBalance(sg.timeBucketKey());
		// MonitorHandler.monitorStrategy(configRepository.fetchMonitoredStrategy(),
		// configRepository.fetchDebugMode(),
		// Strategy.class.getName(), String.valueOf(s == null ? 0 : s.getId()),
		// "balance is " + balance);
		// 余量大于0，如果余量大于单个的消耗，返回有量
		// if (balance > 0) {
		if (balance >= singleBudget) {
			return true;
			// }
			// 余量等于0，如果最新更新时间为0，代表是初始状态，返回有量
		}
		if (balance == 0) {
			long ut = strategyRepository.fetchUpdateTime(sg.latestConsumeKey());
			if (ut == 0)
				return true;
			// 余量小于0
		}
		if (balance < singleBudget) {
			long ut = strategyRepository.fetchUpdateTime(sg.latestConsumeKey());
			int bucket = strategyRepository.strategyGroupBucketInterval(ut, sg);
			double timeBucketAmount = strategyRepository.getStrategyGroupTimeBucketAmount(sg);
			// 只有余量和待追的量相加大于0，才可以出量
			if ((balance + bucket * timeBucketAmount) >= singleBudget) {
				return true;
			}
		}

		return false;
	}

	/**
	 * 根据speedBase判断余量: 1.余量是否 > 0 2.如果余量 <= 0看最新的updateTime时间和当前时间是否在同一个时间段内
	 * 
	 * @param s
	 * @return
	 */
	boolean haveBalance(Strategy s, double singleBudget) {
		double balance = strategyRepository.fetchBalance(s.timeBucketKey());

		// if (balance > 0) {
		if (balance >= singleBudget) {
			return true;
		}
		if (balance == 0) {
			long ut = strategyRepository.fetchUpdateTime(s.latestConsumeKey());
			if (ut == 0)
				return true;
		}
		if (balance < singleBudget) {
			long ut = strategyRepository.fetchUpdateTime(s.latestConsumeKey());
			int bucket = strategyRepository.bucketInterval(ut, s);
			double timeBucketAmount = strategyRepository.getTimeBucketAmount(s);
			// 只有余量和待追的量相加大于0，才可以出量
			if ((balance + bucket * timeBucketAmount) >= singleBudget) {
				return true;
			}
		}
		return false;
	}

	double getCountInList(List<Double> list, int index) {
		if (list.size() <= index)
			return 0;
		if (list.get(index) == null)
			return 0;
		Number i = list.get(index);
		return i.doubleValue();
	}

	// Double fetchAmount(String key) {
	// }

	boolean compareBalance(String key, Number target) {
		if (target == null || target.doubleValue() <= 0)
			return true;
		double amount = strategyRepository.fetchAmount(key);
		if (amount >= target.doubleValue()) {
			MonitorHandler.monitorStrategy(configRepository.fetchMonitoredStrategy(), configRepository.fetchDebugMode(),
					key, "", amount + " lager than " + target);
			return false;
		}
		return true;
	}

	boolean compareBudget(String key, Number target, Double singleBudget) {
		if (target == null || target.doubleValue() <= 0)
			return true;
		double budget = strategyRepository.fetchAmount(key);
		if ((target.doubleValue() - budget) < singleBudget) {
			MonitorHandler.monitorStrategy(configRepository.fetchMonitoredStrategy(), configRepository.fetchDebugMode(),
					key, "", (target.doubleValue() - budget) + " lager than " + singleBudget);
			return false;
		}
		return true;
	}

	/**
	 * 给定的策略选出
	 * 
	 * @param s
	 * @return 当策略通过筛选则ran'h
	 */
	public boolean whetherHaveBalance(Strategy s) {
		// long time = System.currentTimeMillis();

		if (s == null) {
			MonitorHandler.monitorStrategy(configRepository.fetchMonitoredStrategy(), configRepository.fetchDebugMode(),
					Strategy.class.getName(), String.valueOf(s == null ? 0 : s.getId()), "is null");
			return false;
		} else if (s.getCampaign() == null) {
			MonitorHandler.monitorStrategy(configRepository.fetchMonitoredStrategy(), configRepository.fetchDebugMode(),
					Strategy.class.getName(), String.valueOf(s == null ? 0 : s.getId()), "campaign is null");
			return false;
		} else if (s.getStrategyGroup() != null && s.getStrategyGroup().getStatus() != 1) {
			MonitorHandler.monitorStrategy(configRepository.fetchMonitoredStrategy(), configRepository.fetchDebugMode(),
					Strategy.class.getName(), String.valueOf(s == null ? 0 : s.getId()),
					"strategygroup is null or status != 1");
			return false;
		}

		// 从redis取得计数的值
		// List<Double> vs = this.strategyRepository.findCountValue(s);
		// double maxImp = getCountInList(vs, 0);
		// double dayImp = getCountInList(vs, 1);
		// double maxClick = getCountInList(vs, 2);
		// double dayClick = getCountInList(vs, 3);
		//
		// double maxBudget = getCountInList(vs, 4);
		// double dayBudget = getCountInList(vs, 5);

		double singleBudget = s.getUnitPrice().doubleValue();

		// 按展示计费CPM
		if (s.getFeeType() == 1) {
			singleBudget = strategyRepository.singleCPMBudget(s.getUnitPrice());
		}

		// // 控总量
		// if (maxImp >= s.getMaxImpressions() && s.getMaxImpressions() > 0)
		// return false;
		// if (maxClick >= s.getMaxClicks() && s.getMaxClicks() > 0)
		// return false;
		// if ((s.getBudget().doubleValue() - maxBudget) < singleBudget &&
		// s.getBudget().doubleValue() > 0)
		// return false;

		if (!this.compareBalance(s.maxImpressionsKey(), s.getMaxImpressions())) {
			return false;
		}
		// logger.info("1 : {}", System.currentTimeMillis() - time);
		// time = System.currentTimeMillis();
		// if (maxImp >= s.getMaxImpressions() && s.getMaxImpressions() > 0)
		// return false;
		if (!this.compareBalance(s.maxClicksKey(), s.getMaxClicks()))
			return false;
		// logger.info("2 : {}", System.currentTimeMillis() - time);
		// time = System.currentTimeMillis();
		// if (maxClick >= s.getMaxClicks() && s.getMaxClicks() > 0)
		// return false;
		if (!this.compareBudget(s.maxBudgetKey(), s.getBudget(), singleBudget))
			return false;
		// logger.info("3 : {}", System.currentTimeMillis() - time);
		// time = System.currentTimeMillis();

		// 控每天的量
		// if (dayImp >= s.getDayImpressions() && s.getDayImpressions() > 0)
		// return false;
		// if (dayClick >= s.getDayClicks() && s.getDayClicks() > 0)
		// return false;
		// if ((s.getDayBudget().doubleValue() - dayBudget) < singleBudget &&
		// s.getDayBudget().doubleValue() > 0)
		// return false;

		if (!this.compareBalance(s.dayImpressionsKey(), s.getDayImpressions()))
			return false;

		// logger.info("4 : {}", System.currentTimeMillis() - time);
		// time = System.currentTimeMillis();

		if (!this.compareBalance(s.dayClicksKey(), s.getDayClicks()))
			return false;

		// logger.info("5 : {}", System.currentTimeMillis() - time);
		// time = System.currentTimeMillis();

		if (!this.compareBudget(s.dayBudgetKey(), s.getDayBudget(), singleBudget))
			return false;
		// logger.info("6 : {}", System.currentTimeMillis() - time);
		// time = System.currentTimeMillis();

		if (isStrategyGroupBalance(s)) {
			// double groupDayBudget = getCountInList(vs, vs.size() - 1);
			double groupDayBudget = this.strategyRepository.fetchAmount(s.getStrategyGroup().dayBudgetKey());

			if ((s.getStrategyGroup().getDayBudget().doubleValue() - groupDayBudget) < singleBudget
					&& s.getStrategyGroup().getDayBudget().doubleValue() > 0) {
				MonitorHandler.monitorStrategy(configRepository.fetchMonitoredStrategy(),
						configRepository.fetchDebugMode(), StrategyGroup.class.getName(),
						String.valueOf(s.getStrategyGroup().getId()),
						(s.getStrategyGroup().getDayBudget().doubleValue() - groupDayBudget) + " < " + singleBudget);
				return false;
			}

			if (s.getStrategyGroup().getSpeedMode() == 0) {
				if (!this.haveStrategyGroupBalance(s, singleBudget)) {
					MonitorHandler.monitorStrategy(configRepository.fetchMonitoredStrategy(),
							configRepository.fetchDebugMode(), StrategyGroup.class.getName(),
							String.valueOf(s.getStrategyGroup().getId()), "have no StrategyGroupBalance");
					return false;
				}
			}

		} else {
			// 如果是平均投放，控每个时间段的量
			if (s.getSpeedMode() == 0) {
				if (!haveBalance(s, singleBudget)) {
					MonitorHandler.monitorStrategy(configRepository.fetchMonitoredStrategy(),
							configRepository.fetchDebugMode(), Strategy.class.getName(), String.valueOf(s.getId()),
							"have no StrategyBalance");
					return false;
				}
			}
		}

		// 控订单
		if (s.getCampaign() != null) {
			Campaign c = s.getCampaign();

			// double campaignMaxImp = getCountInList(vs, 6);
			// double campaignDayImp = getCountInList(vs, 7);
			// double campaignMaxClick = getCountInList(vs, 8);
			// double campaignDayClick = getCountInList(vs, 9);
			// double campaignMaxBudget = getCountInList(vs, 10);
			// double campaignDayBudget = getCountInList(vs, 11);
			//
			// if (campaignMaxImp >= s.getCampaign().getMaxImpressions() &&
			// s.getCampaign().getMaxImpressions() > 0)
			// return false;
			// if (campaignDayImp >= s.getCampaign().getDayImpressions() &&
			// s.getCampaign().getDayImpressions() > 0)
			// return false;
			//
			// if (campaignMaxClick >= s.getCampaign().getMaxClicks() &&
			// s.getCampaign().getMaxClicks() > 0)
			// return false;
			// if (campaignDayClick >= s.getCampaign().getDayClicks() &&
			// s.getCampaign().getDayClicks() > 0)
			// return false;

			if (!this.compareBalance(c.maxImpressionsKey(), c.getMaxImpressions()))
				return false;
			// logger.info("7 : {}", System.currentTimeMillis() - time);
			// time = System.currentTimeMillis();

			if (!this.compareBalance(c.dayImpressionsKey(), c.getDayImpressions()))
				return false;
			// logger.info("8 : {}", System.currentTimeMillis() - time);
			// time = System.currentTimeMillis();

			if (!this.compareBalance(c.maxClicksKey(), c.getMaxClicks()))
				return false;
			// logger.info("9 : {}", System.currentTimeMillis() - time);
			// time = System.currentTimeMillis();

			if (!this.compareBalance(c.dayClicksKey(), c.getDayClicks()))
				return false;
			// logger.info("10 : {}", System.currentTimeMillis() - time);
			// time = System.currentTimeMillis();

			// double singleCampaignBudget =
			// s.getCampaign().getUnitPrice().doubleValue();
			// if (s.getCampaign().getFeeType() == 1) {
			// singleBudget =
			// strategyRepository.singleCPMBudget(s.getCampaign().getUnitPrice());
			// }
			//
			// if ((s.getCampaign().getBudget().doubleValue() -
			// campaignMaxBudget) < singleBudget
			// && (s.getCampaign().getBudget() != null &&
			// s.getCampaign().getBudget().doubleValue() > 0))
			// return false;
			// if ((s.getCampaign().getBudgetDay().doubleValue() -
			// campaignDayBudget) < singleBudget
			// && (s.getCampaign().getBudgetDay() != null &&
			// s.getCampaign().getBudgetDay().doubleValue() > 0))
			// return false;

			if (!this.compareBudget(c.maxBudgetKey(), c.getBudget(), singleBudget))
				return false;
			// logger.info("11 : {}", System.currentTimeMillis() - time);
			// time = System.currentTimeMillis();

			if (!this.compareBudget(c.dayBudgetKey(), c.getBudgetDay(), singleBudget))
				return false;
			// logger.info("12 : {}", System.currentTimeMillis() - time);
			// time = System.currentTimeMillis();

		}
		return true;
	}

	/**
	 * 检查是否需要策略分组控量
	 * 
	 * @param s
	 * @return
	 */
	boolean isStrategyGroupBalance(Strategy s) {
		return s.getStrategyGroup() != null;
	}
	// double toSingleServerAmount(Number amount) {
	// return amount.doubleValue() / configRepository.fetchServerNumber();
	// }

	public void clickCount(Strategy s) {

		this.strategyRepository.countClick(s);
	}

	public void impressionsCount(Strategy s) {
		this.strategyRepository.countImpressions(s);
	}

	public void warmUpAllAssociation() {
		adSpaceRepository.warmUpAllAssociation();
	}

	public AdSpace getAdSpace(long id) {
		return adSpaceRepository.getAdSpaceByIdFrmDB(id);
	}

	public void warmUpStrategy() {
		strategyRepository.warmUpStrategy();
	}

	public void warmUpConfig() {
		configRepository.warmAllConfig();
	}

	public List<Strategy> findAvailableStrategy() {
		return this.strategyRepository.findAvailable();
	}

	public boolean checkflowFilter() {
		int f = this.configRepository.fetchFilterRatio();
		if (f == 10)
			return false;
		Random r = new Random();
		int i = r.nextInt(10);
		return i < f;
	}

	public List<String> fetchExcludeCampaign() {
		return this.configRepository.fetchExcludeCampaign();
	}

	public Double getRatio(int campaignId) {
		List<String> exCids = fetchExcludeCampaign();
		if (!exCids.contains(String.valueOf(campaignId)))
			return 1.0;
		return this.configatio;
	}

	public StrategyRepository getStrategyRepository() {
		return strategyRepository;
	}

	public void setStrategyRepository(StrategyRepository strategyRepository) {
		this.strategyRepository = strategyRepository;
	}

	public void unbond() {
		this.strategyRepository.unbond();
	}

	public void placeGuid(Campaign campaign, AdSpace adSpace, Strategy s, StrategyGroup sg) {

	}

	// @Resource(name = "guidRedisTemplate")
	// private RedisTemplate<String, GuidValueObject> guidRedisTemplate;
	//
	// @Resource(name = "jsonTestRedisTemplate")
	// private RedisTemplate<String, GuidValueObject> jsonTestRedisTemplate;
	//
	// public void pb(int limit, GuidValueObject g) throws IOException {
	// for(int i = 0; i < limit; i++) {
	// String guid = UUID.randomUUID().toString().replace("-", "");
	// guidRedisTemplate.opsForValue().set(guid, g);
	// }
	// }
	//
	// public void aset(GuidValueObject g, String key) {
	// guidRedisTemplate.opsForValue().set(key, g);
	// }
	//
	// public GuidValueObject aget(String key) {
	// return guidRedisTemplate.opsForValue().get(key);
	// }
	//
	// public void json(int limit, GuidValueObject g) throws IOException {
	// for(int i = 0; i < limit; i++) {
	// String guid = UUID.randomUUID().toString().replace("-", "");
	// jsonTestRedisTemplate.opsForValue().set(guid, g);
	// }
	// }

}
